class_name Card
extends Control

# 卡牌数据结构
@export var card_id: int = 0
@export var card_name: String = ""
@export var card_type: String = ""  # "unit" 或 "spell"
@export var cost: int = 0
@export var attack: int = 0
@export var health: int = 0
@export var max_health: int = 0
@export var description: String = ""
@export var effect: String = ""
@export var effect_value: int = 0
@export var rarity: String = ""
@export var image_path: String = ""

# 纹理缓存，避免重复加载
var cached_texture: Texture2D = null

# 卡牌状态
@export var is_in_hand: bool = true
@export var is_on_board: bool = false
@export var is_dragging: bool = false
@export var can_be_played: bool = true  # 默认设置为true，允许拖动
@export var has_summoning_sickness: bool = true
@export var has_attacked_this_turn: bool = false
@export var is_frozen: bool = false
@export var can_attack: bool = false  # 是否可以攻击

# UI 组件引用
@onready var card_frame: Panel = $CardFrame
@onready var card_image: TextureRect = $CardFrame/CardImage
@onready var cost_label: Label = $CardFrame/CostLabel
@onready var name_label: Label = $CardFrame/NameLabel
@onready var description_label: Label = $CardFrame/DescriptionLabel
@onready var attack_label: Label = $CardFrame/AttackLabel
@onready var health_label: Label = $CardFrame/HealthLabel

func _ready():
	# 验证UI组件是否正确获取
	if not cost_label:
		print("Card _ready: 警告 - cost_label未找到")
	if not name_label:
		print("Card _ready: 警告 - name_label未找到")
	if not description_label:
		print("Card _ready: 警告 - description_label未找到")
	if not attack_label:
		print("Card _ready: 警告 - attack_label未找到")
	if not health_label:
		print("Card _ready: 警告 - health_label未找到")
	if not card_image:
		print("Card _ready: 警告 - card_image未找到")
	
	# 设置鼠标过滤器以接收鼠标事件
	mouse_filter = Control.MOUSE_FILTER_STOP
	
	# 确保CardFrame和所有子节点不会阻挡鼠标事件
	if card_frame:
		card_frame.mouse_filter = Control.MOUSE_FILTER_PASS
		# 设置所有子节点的鼠标过滤器
		for child in card_frame.get_children():
			if child is Control:
				child.mouse_filter = Control.MOUSE_FILTER_PASS
	
	# 连接输入信号 - 确保只连接一次
	_connect_gui_input_signal()
	
	# 连接鼠标事件信号
	_connect_mouse_signals()
	
	# 确保节点可以接收焦点
	focus_mode = Control.FOCUS_ALL
	
	# 设置默认大小和显示属性
	custom_minimum_size = Vector2(120, 160)
	size = Vector2(120, 160)
	z_index = 1  # 设置默认层级
	visible = true  # 确保可见
	modulate.a = 1.0  # 确保不透明
	
	# 初始化UI
	update_card_display()

# 信号定义
signal card_clicked(card: Control)
signal card_drag_started(card: Control)
signal card_drag_ended(card: Control, dropped_on_board: bool)
signal card_played(card: Control)
signal card_attacked(attacker: Control, target)
signal card_mouse_entered(card: Control)
signal card_mouse_exited(card: Control)

# 拖拽相关变量
var drag_offset: Vector2
var original_position: Vector2
var original_parent: Node
var drag_preview: Control

# 统一的信号连接函数
func _connect_gui_input_signal():
	"""统一处理gui_input信号连接，避免重复连接"""
	if not gui_input.is_connected(_on_gui_input):
		var result = gui_input.connect(_on_gui_input)
		if result != OK:
			print("Card: ❌ gui_input信号连接失败，错误代码: ", result)

func _connect_mouse_signals():
	"""连接鼠标进入和离开事件"""
	print("=== Card _connect_mouse_signals: 开始连接鼠标信号 - ", card_name, " ===")
	print("Card _connect_mouse_signals: mouse_filter = ", mouse_filter)
	print("Card _connect_mouse_signals: focus_mode = ", focus_mode)
	
	if not mouse_entered.is_connected(_on_mouse_entered):
		var result = mouse_entered.connect(_on_mouse_entered)
		if result != OK:
			print("Card: ❌ mouse_entered信号连接失败，错误代码: ", result)
		else:
			print("Card: ✅ mouse_entered信号连接成功 - ", card_name)
	else:
		print("Card: ⚠️ mouse_entered信号已连接 - ", card_name)
	
	if not mouse_exited.is_connected(_on_mouse_exited):
		var result = mouse_exited.connect(_on_mouse_exited)
		if result != OK:
			print("Card: ❌ mouse_exited信号连接失败，错误代码: ", result)
		else:
			print("Card: ✅ mouse_exited信号连接成功 - ", card_name)
	else:
		print("Card: ⚠️ mouse_exited信号已连接 - ", card_name)

func set_card_data(data: Dictionary):
	"""设置卡牌数据"""
	print("Card set_card_data: === 函数开始执行 ===")
	card_id = data.get("id", 0)
	card_name = data.get("name", "")
	card_type = data.get("type", "")
	cost = data.get("cost", 0)
	attack = data.get("attack", 0)
	health = data.get("health", 0)
	max_health = health
	description = data.get("description", "")
	effect = data.get("effect", "")
	effect_value = data.get("effect_value", 0)
	rarity = data.get("rarity", "")
	image_path = data.get("image_path", "")
	
	print("Card set_card_data: 开始设置卡牌数据")
	print("Card set_card_data: 接收到的数据=", data)
	print("Card set_card_data: 数据设置完成，卡牌名称=", card_name, "，费用=", cost)
	
	# 确保卡牌处于正常显示状态
	is_dragging = false
	modulate.a = 1.0
	# z_index 保持当前值，避免覆盖拖拽时的层级设置
	visible = true
	
	print("Card set_card_data: 确保mouse_filter为STOP，focus_mode为FOCUS_ALL")
	# 确保鼠标过滤器设置正确
	mouse_filter = Control.MOUSE_FILTER_STOP
	focus_mode = Control.FOCUS_ALL
	
	print("Card set_card_data: 准备连接鼠标信号，卡牌名称: ", card_name)
	print("Card set_card_data: 即将调用_connect_mouse_signals()...")
	# 重新连接鼠标信号（现在card_name已设置）
	_connect_mouse_signals()
	print("Card set_card_data: _connect_mouse_signals()调用完成")
	print("Card set_card_data: 鼠标信号连接完成")
	
	# 确保信号连接正常
	_connect_gui_input_signal()
	print("Card set_card_data: gui_input信号连接完成")
	
	# 直接更新显示
	update_card_display()

func update_card_display():
	"""更新卡牌显示"""
	# 动态获取UI组件并更新
	var cost_node = get_node_or_null("CardFrame/CostLabel")
	if cost_node:
		cost_node.text = str(cost)
	else:
		print("Card update_card_display: 警告 - CostLabel节点不存在")
		
	var name_node = get_node_or_null("CardFrame/NameLabel")
	if name_node:
		name_node.text = card_name
	else:
		print("Card update_card_display: 警告 - NameLabel节点不存在")
		
	var desc_node = get_node_or_null("CardFrame/DescriptionLabel")
	if desc_node:
		desc_node.text = description
	else:
		print("Card update_card_display: 警告 - DescriptionLabel节点不存在")
	
	# 加载卡牌图片（使用缓存机制避免重复加载）
	var image_node = get_node_or_null("CardFrame/CardImage")
	if image_node and image_path != "":
		# 如果纹理未缓存或路径发生变化，则重新加载
		if cached_texture == null:
			cached_texture = load(image_path) as Texture2D
			if cached_texture:
				print("Card update_card_display: 成功加载并缓存纹理: ", image_path)
			else:
				print("Card update_card_display: 警告 - 无法加载图片: ", image_path)
		
		# 使用缓存的纹理
		if cached_texture:
			image_node.texture = cached_texture
	elif image_node:
		print("Card update_card_display: 警告 - 图片路径为空")
	else:
		print("Card update_card_display: 警告 - CardImage节点不存在")
	
	# 根据卡牌类型显示不同信息
	var attack_node = get_node_or_null("CardFrame/AttackLabel")
	var health_node = get_node_or_null("CardFrame/HealthLabel")
	
	if card_type == "unit":
		if attack_node:
			attack_node.text = str(attack)
			attack_node.visible = true
		else:
			print("Card update_card_display: 警告 - AttackLabel节点不存在")
			
		if health_node:
			health_node.text = str(health)
			health_node.visible = true
		else:
			print("Card update_card_display: 警告 - HealthLabel节点不存在")
	else:
		# 法术卡隐藏攻击力和生命值
		if attack_node:
			attack_node.visible = false
		if health_node:
			health_node.visible = false
	
	# 根据稀有度设置边框颜色
	set_rarity_color()
	
	# 更新可打出状态
	update_playable_state()

func set_rarity_color():
	"""根据稀有度设置边框颜色"""
	if not card_frame:
		return
	
	match rarity:
		"common":
			card_frame.modulate = Color.WHITE
		"rare":
			card_frame.modulate = Color.DODGER_BLUE
		"legendary":
			card_frame.modulate = Color.GOLD
		_:
			card_frame.modulate = Color.GRAY

func _on_gui_input(event: InputEvent):
	"""处理GUI输入事件"""
	if event is InputEventMouseButton:
		var mouse_event = event as InputEventMouseButton
		
		if mouse_event.button_index == MOUSE_BUTTON_LEFT and mouse_event.pressed:
			# 点击出牌
			print("Card _on_gui_input: ✅ 左键点击确认，尝试出牌 - ", card_name)
			handle_card_click()
			accept_event()

func handle_card_click():
	"""处理卡牌点击 - 发射点击信号"""
	
	# 发射卡牌点击信号，让外部处理具体逻辑
	card_clicked.emit(self)

func _on_mouse_entered():
	"""鼠标进入卡牌区域"""
	
	# 发射鼠标进入信号，让Main.gd显示提示框
	card_mouse_entered.emit(self)

func _on_mouse_exited():
	"""鼠标离开卡牌区域"""
	
	# 发射鼠标离开信号，让Main.gd隐藏提示框
	card_mouse_exited.emit(self)

func start_drag(mouse_pos: Vector2):
	"""开始拖拽"""
	if not is_in_hand:
		return
	
	is_dragging = true
	# 计算鼠标相对于卡牌的偏移
	drag_offset = mouse_pos
	original_position = position
	original_parent = get_parent()
	
	# 创建拖拽预览
	create_drag_preview()
	
	# 发送拖拽开始信号
	card_drag_started.emit(self)
	
	print("开始拖拽: ", card_name)

func update_drag_position(_mouse_pos: Vector2):
	"""更新拖拽位置"""
	if not is_dragging:
		return
	
	# 获取全局鼠标位置
	var global_mouse_pos = get_global_mouse_position()
	
	# 更新卡牌位置 - 转换为父节点的本地坐标
	if get_parent():
		# 对于HBoxContainer等容器，直接使用全局坐标转换
		var local_pos = global_mouse_pos - get_parent().global_position
		position = local_pos - drag_offset
	
	# 更新拖拽预览位置
	if drag_preview:
		drag_preview.global_position = global_position

func end_drag(_mouse_pos: Vector2):
	"""结束拖拽"""
	if not is_dragging:
		return
	
	is_dragging = false
	
	# 清理拖拽预览
	cleanup_drag_preview()
	
	# 检查是否拖拽到了战场区域
	var dropped_on_board = check_if_dropped_on_board()
	
	# 发送拖拽结束信号，让外部处理
	card_drag_ended.emit(self, dropped_on_board)
	
	# 如果没有被外部处理，则返回原位置
	if not dropped_on_board:
		return_to_hand()

func create_drag_preview():
	"""创建拖拽预览"""
	# 简单实现：改变透明度
	modulate.a = 0.7
	# 提升层级
	z_index = 100

func cleanup_drag_preview():
	"""清理拖拽预览"""
	# 恢复透明度
	modulate.a = 1.0
	# 恢复到正常层级（不是0，而是1）
	z_index = 1

func check_if_dropped_on_board() -> bool:
	"""检查是否拖拽到了战场区域"""
	# 获取当前鼠标位置
	var mouse_pos = get_global_mouse_position()
	
	# 尝试找到战场区域（支持不同场景）
	var scene_root = get_tree().current_scene
	var board_area = null
	
	# 首先尝试Main场景的玩家战场容器路径
	if scene_root.has_node("GameUI/PlayerBoard/PlayerBoardContainer"):
		board_area = scene_root.get_node("GameUI/PlayerBoard/PlayerBoardContainer")
	# 然后尝试Main场景的战场面板路径
	elif scene_root.has_node("GameUI/PlayerBoard"):
		board_area = scene_root.get_node("GameUI/PlayerBoard")
	# 最后尝试CardTest场景的路径
	elif scene_root.has_node("BoardArea"):
		board_area = scene_root.get_node("BoardArea")
	
	if board_area:
		var board_rect = Rect2(board_area.global_position, board_area.size)
		return board_rect.has_point(mouse_pos)
	
	return false

func can_play_card() -> bool:
	"""检查是否可以打出卡牌"""
	# 这里需要检查法力值、目标等条件
	# 暂时返回true，后续会在GameManager中实现具体逻辑
	return true

func play_card():
	"""打出卡牌"""
	print("Card play_card: 开始出牌 - ", card_name, " 类型=", card_type)
	
	# 发送出牌信号，让GameManager处理法力消耗等逻辑
	card_played.emit(self)
	
	if card_type == "unit":
		# 单位卡放置到战场
		place_on_board()
		move_to_board()
	elif card_type == "spell":
		# 法术卡不在这里销毁，让GameManager统一处理
		# 这样可以确保法术效果能正确显示
		print("Card play_card: 法术卡将由GameManager处理效果和销毁")

func move_to_board():
	"""将卡牌移动到战场区域"""
	print("Card move_to_board: ", card_name, " 开始移动到战场")
	
	# 不在这里直接操作DOM，而是通过信号让Main场景处理
	# 这样可以确保战场布局的一致性
	
	# 发送信号，让Main场景的GameManager处理战场添加
	# 这个函数主要用于设置卡牌的战场状态
	is_on_board = true
	is_in_hand = false
	
	# 调整大小（战场上的卡牌可以小一些）
	scale = Vector2(0.8, 0.8)
	
	# 重置位置，让容器自动布局
	position = Vector2.ZERO
	
	print("Card move_to_board: ", card_name, " 状态已更新为战场状态")

func place_on_board():
	"""放置到战场"""
	is_on_board = true
	can_attack = false  # 召唤失调，本回合不能攻击

func execute_spell_effect():
	"""执行法术效果"""
	# 这里可以根据不同的法术卡实现不同的效果
	# 暂时只是一个占位符
	pass

func destroy_card():
	"""销毁卡牌"""
	queue_free()

func return_to_hand():
	"""返回手牌"""
	# 这里需要实现将卡牌从战场移回手牌的逻辑
	# 暂时只是一个占位符
	pass

func attack_target(target):
	"""攻击目标"""
	if not can_attack:
		return
	
	if target:
		# 双方互相造成伤害
		target.take_damage(attack)
		take_damage(target.attack)
		
		# 攻击后不能再次攻击
		can_attack = false

func take_damage(damage: int):
	"""受到伤害"""
	health -= damage
	
	# 更新显示
	update_card_display()
	
	# 检查是否死亡
	if health <= 0:
		die()

func heal(amount: int):
	"""治疗"""
	health = min(health + amount, max_health)
	update_card_display()

func die():
	"""死亡"""
	print(card_name, " 死亡了")
	
	# 触发亡语效果
	if has_meta("deathrattle_aoe_damage"):
		print(card_name, " 触发亡语效果")
		# 通过GameManager触发亡语效果
		if GameManager:
			# 判断是玩家还是AI的单位
			var player_type = GameManager.PlayerType.PLAYER if self in GameManager.player_board else GameManager.PlayerType.AI
			GameManager.execute_deathrattle_aoe(self, player_type)
	
	# 不再直接销毁卡牌，由GameManager管理生命周期

func set_playable(playable: bool):
	"""设置是否可打出"""
	can_be_played = playable
	update_playable_state()

func update_playable_state():
	"""更新可打出状态的视觉效果"""
	if can_be_played:
		modulate = Color(1.0, 1.0, 1.0, 1.0)  # 正常颜色
	else:
		modulate = Color(0.7, 0.7, 0.7, 1.0)  # 不可打出时变暗

func reset_turn_state():
	"""重置回合状态"""
	can_attack = true  # 新回合可以攻击

func get_card_data() -> Dictionary:
	"""获取卡牌数据"""
	return {
		"id": card_id,
		"name": card_name,
		"type": card_type,
		"cost": cost,
		"attack": attack,
		"health": health,
		"max_health": max_health,
		"description": description,
		"effect": effect,
		"effect_value": effect_value,
		"rarity": rarity,
		"image_path": image_path
	}

func _exit_tree():
	"""节点被移除时清理资源"""
	cleanup_resources()

func cleanup_resources():
	"""清理纹理资源，防止内存泄漏"""
	if cached_texture:
		print("Card cleanup_resources: 清理缓存纹理资源: ", image_path)
		cached_texture = null

func reset_card_state():
	"""重置卡牌状态，用于重新洗牌时"""
	# 重置生命值到最大值
	health = max_health
	
	# 重置战斗状态
	can_attack = true
	can_be_played = true
	
	# 重置位置状态
	is_in_hand = false
	is_on_board = false
	
	# 重置视觉状态
	visible = true
	modulate = Color.WHITE
	scale = Vector2.ONE
	position = Vector2.ZERO
	
	# 更新显示
	update_card_display()
	
	print("Card reset_card_state: 重置卡牌状态 - ", card_name)
